迷宫问题
用循环模拟压栈来实现迷宫问题
我们可以用一个二维数组(N*N)来表示迷宫,1表示路,0表示墙,我们把下方当成迷宫入口,出口为数组右方,此迷宫有两个出口。
需要建立一个结构体arg用来存放关于迷宫(二维数组)的信息。也就是存二维数组的两个下标
然后创建关于用来压栈的结构体
迷宫每个节点都有4个方向可以探寻。碰到墙壁(0)或者边界则此路不通
传迷宫的入口进去也就是数组gMaze[5][2]的信息,这时我们需要传5,2,然后再传一个整型用来标记迷宫的状态,用arg.att表示。
arg.att:这个状态用来标记我们是否试走过 此处 的四个方位,因为0是墙,1是路,所以我们用2来表示我们试过此处的左边能不能通行,3用来表示此处的上方是否通行,4表示右边,5表示下边。用6来表示出口。假如说试过左边不能走,我们就将标记改为3,让他继续试上边能不能走。
进入循环
进入循环之前,先将5,2以及初始标记值2压进栈。
迷宫出口条件:
结束条件为,如果目标走到数组右侧,也就是gMaze[ ][N-1]结束,然后跳出整个循环。
(如果在这里结束,我们则只能找到一条通路,我们让while循环来决定是否结束,此时便能找出多个出口)
先看下面的此处坐标各个方向能不能走,再看下面这段话:
保存每一条路:
如果他能走到这里就说明是一条通路,这时数组里的数据就是走过的一条路径,这时我们创建一个指针数组,每次走到这里,我们就动态开辟一块内存。复制这个数组到该内存中,然后让指针数组来保存这个内存地址,然后让指针数组的下标++,实现保存每一种通路求出最短路径:
我们动态开辟一块内存用来保存gMaze数组,一个变量k=0; 判断条件为(如果k==0 || 栈的大小 <=k) 我们就将此时的数组保存起来,然后将k更新为栈的大小值。
这样我们就会将第一次的数组保存起来,后面不断的将栈最小时候的数组替换到当前动态开辟的内存中,实现最短路径
保存栈顶元素
然后我们查看栈顶元素,也就是把当前的坐标,以及此处的状态复制到另一个argnext中
- 左边是否可行
先看左边能不能走
如果argnext.att<=2说明是刚进来,还没有试左边能不能走,因此进入判左语句中
左边能走我们,将数组该位置的值改为2,并且打印这个数组。
将argnext.x -= 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明左边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为3,说明我们已经走过左边,并且能走,
改过当前位置的状态之后,因为此处的左方是能走通的。因此我们需要将左方的坐标以及初始状态也压入栈内,
左边能走了,因为下面还有试其他方向的语句,我们让它每次只走一条路,因此我们需要continue来跳出本次循环,假如没有continue可能会使程序出错。
- 上边是否可行
试过左边之后,试上边能不能走
如果argnext.att<=3说明是已经试过左边,然后来试上边。
上边能走我们,将数组该位置的值改为3,并且打印这个数组。
将argnext.y -= 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明上边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为4,说明我们已经走过上边,并且能走,
改过当前位置的状态之后,因为此处的上方是能走通的。因此我们需要将上方的坐标以及初始状态也压入栈内。然后跳出本次循环。
- 右边是否可行
试过上边之后,试右边能不能走
如果argnext.att<=4说明是已经试过上边,然后来试右边。
右边能走我们,将数组该位置的值改为4,并且打印这个数组。
将argnext.y += 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明右边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为5,说明我们已经走过右边,并且能走,
改过当前位置的状态之后,因为此处的右方是能走通的。因此我们需要将上方的坐标以及初始状态也压入栈内。然后跳出本次循环。
- 下边是否可行
试过右边之后,试下边能不能走
如果argnext.att<=5说明是已经试过右边,然后来试下边。
右边能走我们,将数组该位置的值改为5,并且打印这个数组。
将argnext.x += 1 后,判断这个点是不是墙、否越界数组,如果符合条件进入语句
进入语句就说明下边是能走的通的,然后我们将栈顶的也就是arg的状态arg.att改为6,说明我们已经走过下边,并且能走,
改过当前位置的状态之后,因为此处的下方是能走通的。因此我们需要将上方的坐标以及初始状态也压入栈内。然后跳出本次循环。
- 出栈
如果能走到最后一步说明这个点的上下左右都不能走,然后我们需要将它的状态置为1,也就是说,把它改成我们没走过的,这样就不影响后面寻找多条路时候我们不能再次走到这里的问题。
然后将这个点Pop出栈。
循环结束条件
这样构成一个循环,结束条件为栈为空,结束条件为栈为空时,我们可以寻找迷宫的多个出口。
每次在循环中打印数组时,我门用一个system(“cls”);来清屏,实现一个看起来像是能动的迷宫(哈哈哈)
代码实现
- 下面是代码实现
#pragma once